#! /usr/bin/env python
# -*- coding:utf-8 -*-

from utils import ChatLogger

__author__ = 'cjay'


class State(object):
    possible_actions = []        # list of possible actions for this state
    action = None             # possible action ( probably it is the first action from possible_actions list)


    def __init__(self, name="statename", fsm=None):
        """
        Initialize base class of states

        @type name: string
        @param name: name of the state-type
        @type fsm: StateMachine
        @param fsm: state machine that contain this state

        """
        self.name = name
        self.states = {}
        self.fsm = fsm

    def activate(self):
        """
        this function run always when state set as current state for the StateMachine
        """
        pass

    def addState(self,state):
        """
        Add state as next possible transition

        @type state: State
        @param state: state
        """
        if not self.states.has_key(state):
            self.states[state.name]=state

    def next(self):
        """
        This method must solve and compute which his added states must be the next current state
        """
        raise NotImplementedError, "You can`t use this class directly. Inherit it"

    def exclude(self, action_name):
        """
        Exclude action with action_name from possible_actions list

        @type action_name: str
        @param action_name: name of excluded action
        """
        if action_name in self.possible_actions:
            self.possible_actions.remove(action_name)

class StartState(State):
    def __init__(self, fsm):
        super(StartState,self).__init__("start_state",fsm)

    def activate(self):
        ChatLogger.getInstance().log(u"Игра началась\n")
        self.possible_actions = ['go_player','go_cpu']
        if self.fsm.player_first:
            self.exclude('go_player')
        else: self.exclude('go_cpu')
        self.action = self.possible_actions[0]

    def next(self):
        if self.action=="go_player":
            return self.states['player_turn_state']
        if self.action=="go_cpu":
            return self.states['cp_turn_state']

class PlayerTurnState(State):
    def __init__(self, fsm):
        super(PlayerTurnState,self).__init__("player_turn_state",fsm)
        self.action = None
        #: @type: FinalStateMachine
        self.fsm

    def activate(self):
        ChatLogger.getInstance().log(u"Ваш ход:\n")
        self.possible_actions = ['fold','blind','dblind','check','call','bet',]
        # if blinds were not made
        self.fsm.min = 0
        self.fsm.max = self.fsm.p_money

        if self.fsm.hasBlind:
            self.exclude('blind')
            self.fsm.min = self.fsm.blind

        if self.fsm.hasBigBlind:
            self.exclude('blind')
            self.exclude('dblind')


        if not self.fsm.hasBigBlind:
            self.exclude('check')
            self.exclude('call')
            self.exclude('bet')
            self.fsm.min = self.fsm.bigblind
            self.fsm.max = self.fsm.bigblind*2
        if  not self.fsm.hasBlind:
            self.exclude('check')
            self.exclude('call')
            self.exclude('bet')
            self.exclude('dblind')
            self.fsm.min = self.fsm.blind
            self.fsm.max = self.fsm.blind*2

        self.fsm.dropped_money = self.fsm.min

        print "balance: ",self.fsm.p_put_money, self.fsm.c_put_money
        # if player need to equalize the rates
        if self.fsm.p_put_money!= self.fsm.c_put_money:
            self.exclude('check')
            self.fsm.min = self.fsm.c_put_money-self.fsm.p_put_money
            self.fsm.dropped_money = self.fsm.min
        # if rates were equalized
        if self.fsm.c_put_money== self.fsm.p_put_money:
            self.exclude('call')

        self.action = self.possible_actions[0]


    def next(self):
        ChatLogger.getInstance().log(u"%s:\n"%self.action)
        print "p_put_money = ", self.fsm.p_put_money
        if self.action == "fold":
            return self.states["loose_state"]

        if self.action == "call":
            self.fsm.p_pay(self.fsm.min)
            return self.states['cp_turn_state']

        if self.action == "bet":
            self.fsm.bets_count+=1
            self.fsm.p_pay(self.fsm.dropped_money)
            return self.states['cp_turn_state']

        if self.action == "dblind":
            self.fsm.hasBigBlind = True
            self.fsm.p_pay(self.fsm.dropped_money)
            return self.states['end_turn_state']

        if self.action == "blind":
            self.fsm.hasBlind = True
            self.fsm.p_pay(self.fsm.dropped_money)
            return self.states['cp_turn_state']
        if self.action == "check":
            self.fsm.p_check = True
            if self.fsm.p_check and self.fsm.cpu_check:
                return self.states['end_turn_state']
            return self.states['cp_turn_state']



class CPTurnState(State):
    paysize = 10
    def __init__(self, fsm):
        super(CPTurnState,self).__init__("cp_turn_state",fsm)

    def activate(self):
        ChatLogger.getInstance().log(u"Ход Блудницы:\n")
        self.possible_actions = ['blind','dblind','check','call','bet','fold']
        # if blinds were not made
        if self.fsm.c_put_money!= self.fsm.p_put_money:
            self.exclude('check')
            self.fsm.min = self.fsm.p_put_money-self.fsm.c_put_money

        elif self.fsm.c_put_money== self.fsm.p_put_money:
            self.exclude('call')

        if self.fsm.hasBlind:
            self.exclude('blind')

        if self.fsm.hasBigBlind:
            self.exclude('blind')
            self.exclude('dblind')

        if not self.fsm.hasBigBlind:
            self.exclude('check')
            self.exclude('call')
            self.exclude('bet')
            self.fsm.min = self.fsm.bigblind

        if  not self.fsm.hasBlind:
            self.exclude('check')
            self.exclude('call')
            self.exclude('bet')
            self.exclude('dblind')
            self.fsm.min = self.fsm.blind

        self.fsm.dropped_money = self.fsm.min



    def solve_action(self):
        self.action = self.possible_actions[0]


        if not self.fsm.hasBigBlind:
            self.action = "dblind"

        if not self.fsm.hasBlind:
            self.action = "blind"
        ChatLogger.getInstance().log(u"%s:\n"%self.action)
        return self.action

    def next(self):
        if self.action == "fold":
            return self.states["win_state"]

        if self.action == "call":
            self.fsm.cp_pay(self.fsm.dropped_money)
            return self.states['player_turn_state']

        if self.action == "bet":
            self.fsm.bets_count+=1
            self.fsm.cp_pay(self.fsm.dropped_money)
            return self.states['player_turn_state']

        if self.action == "dblind":
            self.fsm.hasBigBlind = True
            self.fsm.cp_pay(self.fsm.dropped_money)
            return self.states['end_turn_state']

        if self.action == "blind":
            self.fsm.hasBlind = True
            self.fsm.cp_pay(self.fsm.dropped_money)
            return self.states['player_turn_state']

        if self.action == "check":
            self.fsm.cpu_check = True
            if self.fsm.p_check and self.fsm.cpu_check:
                return self.states['end_turn_state']
            return self.states['player_turn_state']

class EndTurnState(State):
    def __init__(self, fsm):
        super(EndTurnState,self).__init__("end_turn_state",fsm)

    def activate(self):
        ChatLogger.getInstance().log(u"Окончание раунда.\n")
        self.possible_actions = ['finish','go_player','go_cpu']
        if len(self.fsm.cards)<4:
            self.exclude('finish')
        if self.fsm.player_first:
            self.exclude('go_player')
        else: self.exclude('go_cpu')


    def solve_action(self):
        self.action = self.possible_actions[0]

    def next(self):
        if self.action == "finish":
            return self.states['finish_state']

        if self.action == "go_cpu":
            return self.states["cp_turn_state"]
        if self.action == "go_player":
            return self.states["player_turn_state"]

class WinState(State):
    def __init__(self, fsm):
        super(WinState,self).__init__("win_state",fsm)

    def activate(self):
        ChatLogger.getInstance().log(u"Вы Выйграли!\n"%self.action)
        self.possible_actions = []
        self.action = None

    def next(self):
        return None

class LooseState(State):
    def __init__(self, fsm):
        super(LooseState,self).__init__("loose_state",fsm)

    def activate(self):
        ChatLogger.getInstance().log(u"Вы проиграли.\n"%self.action)
        self.possible_actions = []
        self.action = None


    def next(self):
        return None

class FinishState(State):
    def __init__(self, fsm):
        super(FinishState,self).__init__("finish_state",fsm)

    def activate(self):
        self.possible_actions = []
        self.action = None

    def next(self):
        ChatLogger.getInstance().log(u"Игра закончена\n")
        return self.states['loose_state']
